home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / PEAR / Command.php < prev    next >
PHP Script  |  2004-10-01  |  12KB  |  398 lines

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 5                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2004 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 3.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available through the world-wide-web at the following url:           |
  11. // | http://www.php.net/license/3_0.txt.                                  |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Stig Bakken <ssb@php.net>                                    |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: Command.php,v 1.23 2004/02/27 02:24:06 cellog Exp $
  20.  
  21.  
  22. require_once "PEAR.php";
  23.  
  24. /**
  25.  * List of commands and what classes they are implemented in.
  26.  * @var array command => implementing class
  27.  */
  28. $GLOBALS['_PEAR_Command_commandlist'] = array();
  29.  
  30. /**
  31.  * List of shortcuts to common commands.
  32.  * @var array shortcut => command
  33.  */
  34. $GLOBALS['_PEAR_Command_shortcuts'] = array();
  35.  
  36. /**
  37.  * Array of command objects
  38.  * @var array class => object
  39.  */
  40. $GLOBALS['_PEAR_Command_objects'] = array();
  41.  
  42. /**
  43.  * Which user interface class is being used.
  44.  * @var string class name
  45.  */
  46. $GLOBALS['_PEAR_Command_uiclass'] = 'PEAR_Frontend_CLI';
  47.  
  48. /**
  49.  * Instance of $_PEAR_Command_uiclass.
  50.  * @var object
  51.  */
  52. $GLOBALS['_PEAR_Command_uiobject'] = null;
  53.  
  54. /**
  55.  * PEAR command class, a simple factory class for administrative
  56.  * commands.
  57.  *
  58.  * How to implement command classes:
  59.  *
  60.  * - The class must be called PEAR_Command_Nnn, installed in the
  61.  *   "PEAR/Common" subdir, with a method called getCommands() that
  62.  *   returns an array of the commands implemented by the class (see
  63.  *   PEAR/Command/Install.php for an example).
  64.  *
  65.  * - The class must implement a run() function that is called with three
  66.  *   params:
  67.  *
  68.  *    (string) command name
  69.  *    (array)  assoc array with options, freely defined by each
  70.  *             command, for example:
  71.  *             array('force' => true)
  72.  *    (array)  list of the other parameters
  73.  *
  74.  *   The run() function returns a PEAR_CommandResponse object.  Use
  75.  *   these methods to get information:
  76.  *
  77.  *    int getStatus()   Returns PEAR_COMMAND_(SUCCESS|FAILURE|PARTIAL)
  78.  *                      *_PARTIAL means that you need to issue at least
  79.  *                      one more command to complete the operation
  80.  *                      (used for example for validation steps).
  81.  *
  82.  *    string getMessage()  Returns a message for the user.  Remember,
  83.  *                         no HTML or other interface-specific markup.
  84.  *
  85.  *   If something unexpected happens, run() returns a PEAR error.
  86.  *
  87.  * - DON'T OUTPUT ANYTHING! Return text for output instead.
  88.  *
  89.  * - DON'T USE HTML! The text you return will be used from both Gtk,
  90.  *   web and command-line interfaces, so for now, keep everything to
  91.  *   plain text.
  92.  *
  93.  * - DON'T USE EXIT OR DIE! Always use pear errors.  From static
  94.  *   classes do PEAR::raiseError(), from other classes do
  95.  *   $this->raiseError().
  96.  */
  97. class PEAR_Command
  98. {
  99.     // {{{ factory()
  100.  
  101.     /**
  102.      * Get the right object for executing a command.
  103.      *
  104.      * @param string $command The name of the command
  105.      * @param object $config  Instance of PEAR_Config object
  106.      *
  107.      * @return object the command object or a PEAR error
  108.      *
  109.      * @access public
  110.      * @static
  111.      */
  112.     function factory($command, &$config)
  113.     {
  114.         if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
  115.             PEAR_Command::registerCommands();
  116.         }
  117.         if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
  118.             $command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
  119.         }
  120.         if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
  121.             return PEAR::raiseError("unknown command `$command'");
  122.         }
  123.         $class = $GLOBALS['_PEAR_Command_commandlist'][$command];
  124.         if (!class_exists($class)) {
  125.             return PEAR::raiseError("unknown command `$command'");
  126.         }
  127.         $ui =& PEAR_Command::getFrontendObject();
  128.         $obj = &new $class($ui, $config);
  129.         return $obj;
  130.     }
  131.  
  132.     // }}}
  133.     // {{{ & getFrontendObject()
  134.  
  135.     /**
  136.      * Get instance of frontend object.
  137.      *
  138.      * @return object
  139.      * @static
  140.      */
  141.     function &getFrontendObject()
  142.     {
  143.         if (empty($GLOBALS['_PEAR_Command_uiobject'])) {
  144.             $GLOBALS['_PEAR_Command_uiobject'] = &new $GLOBALS['_PEAR_Command_uiclass'];
  145.         }
  146.         return $GLOBALS['_PEAR_Command_uiobject'];
  147.     }
  148.  
  149.     // }}}
  150.     // {{{ & setFrontendClass()
  151.  
  152.     /**
  153.      * Load current frontend class.
  154.      *
  155.      * @param string $uiclass Name of class implementing the frontend
  156.      *
  157.      * @return object the frontend object, or a PEAR error
  158.      * @static
  159.      */
  160.     function &setFrontendClass($uiclass)
  161.     {
  162.         if (is_object($GLOBALS['_PEAR_Command_uiobject']) &&
  163.               is_a($GLOBALS['_PEAR_Command_uiobject'], $uiclass)) {
  164.             return $GLOBALS['_PEAR_Command_uiobject'];
  165.         }
  166.         if (!class_exists($uiclass)) {
  167.             $file = str_replace('_', '/', $uiclass) . '.php';
  168.             if (PEAR_Command::isIncludeable($file)) {
  169.                 include_once $file;
  170.             }
  171.         }
  172.         if (class_exists($uiclass)) {
  173.             $obj = &new $uiclass;
  174.             // quick test to see if this class implements a few of the most
  175.             // important frontend methods
  176.             if (method_exists($obj, 'userConfirm')) {
  177.                 $GLOBALS['_PEAR_Command_uiobject'] = &$obj;
  178.                 $GLOBALS['_PEAR_Command_uiclass'] = $uiclass;
  179.                 return $obj;
  180.             } else {
  181.                 $err = PEAR::raiseError("not a frontend class: $uiclass");
  182.                 return $err;
  183.             }
  184.         }
  185.         $err = PEAR::raiseError("no such class: $uiclass");
  186.         return $err;
  187.     }
  188.  
  189.     // }}}
  190.     // {{{ setFrontendType()
  191.  
  192.     // }}}
  193.     // {{{ isIncludeable()
  194.  
  195.     /**
  196.      * @param string $path relative or absolute include path
  197.      * @return boolean
  198.      * @static
  199.      */
  200.     function isIncludeable($path)
  201.     {
  202.         if (file_exists($path) && is_readable($path)) {
  203.             return true;
  204.         }
  205.         $ipath = explode(PATH_SEPARATOR, ini_get('include_path'));
  206.         foreach ($ipath as $include) {
  207.             $test = realpath($include . DIRECTORY_SEPARATOR . $path);
  208.             if (file_exists($test) && is_readable($test)) {
  209.                 return true;
  210.             }
  211.         }
  212.         return false;
  213.     }
  214.  
  215.     /**
  216.      * Set current frontend.
  217.      *
  218.      * @param string $uitype Name of the frontend type (for example "CLI")
  219.      *
  220.      * @return object the frontend object, or a PEAR error
  221.      * @static
  222.      */
  223.     function setFrontendType($uitype)
  224.     {
  225.         $uiclass = 'PEAR_Frontend_' . $uitype;
  226.         return PEAR_Command::setFrontendClass($uiclass);
  227.     }
  228.  
  229.     // }}}
  230.     // {{{ registerCommands()
  231.  
  232.     /**
  233.      * Scan through the Command directory looking for classes
  234.      * and see what commands they implement.
  235.      *
  236.      * @param bool   (optional) if FALSE (default), the new list of
  237.      *               commands should replace the current one.  If TRUE,
  238.      *               new entries will be merged with old.
  239.      *
  240.      * @param string (optional) where (what directory) to look for
  241.      *               classes, defaults to the Command subdirectory of
  242.      *               the directory from where this file (__FILE__) is
  243.      *               included.
  244.      *
  245.      * @return bool TRUE on success, a PEAR error on failure
  246.      *
  247.      * @access public
  248.      * @static
  249.      */
  250.     function registerCommands($merge = false, $dir = null)
  251.     {
  252.         if ($dir === null) {
  253.             $dir = dirname(__FILE__) . '/Command';
  254.         }
  255.         $dp = @opendir($dir);
  256.         if (empty($dp)) {
  257.             return PEAR::raiseError("registerCommands: opendir($dir) failed");
  258.         }
  259.         if (!$merge) {
  260.             $GLOBALS['_PEAR_Command_commandlist'] = array();
  261.         }
  262.         while ($entry = readdir($dp)) {
  263.             if ($entry{0} == '.' || substr($entry, -4) != '.php' || $entry == 'Common.php') {
  264.                 continue;
  265.             }
  266.             $class = "PEAR_Command_".substr($entry, 0, -4);
  267.             $file = "$dir/$entry";
  268.             include_once $file;
  269.             // List of commands
  270.             if (empty($GLOBALS['_PEAR_Command_objects'][$class])) {
  271.                 $GLOBALS['_PEAR_Command_objects'][$class] = &new $class($ui, $config);
  272.             }
  273.             $implements = $GLOBALS['_PEAR_Command_objects'][$class]->getCommands();
  274.             foreach ($implements as $command => $desc) {
  275.                 $GLOBALS['_PEAR_Command_commandlist'][$command] = $class;
  276.                 $GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc;
  277.             }
  278.             $shortcuts = $GLOBALS['_PEAR_Command_objects'][$class]->getShortcuts();
  279.             foreach ($shortcuts as $shortcut => $command) {
  280.                 $GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command;
  281.             }
  282.         }
  283.         return true;
  284.     }
  285.  
  286.     // }}}
  287.     // {{{ getCommands()
  288.  
  289.     /**
  290.      * Get the list of currently supported commands, and what
  291.      * classes implement them.
  292.      *
  293.      * @return array command => implementing class
  294.      *
  295.      * @access public
  296.      * @static
  297.      */
  298.     function getCommands()
  299.     {
  300.         if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
  301.             PEAR_Command::registerCommands();
  302.         }
  303.         return $GLOBALS['_PEAR_Command_commandlist'];
  304.     }
  305.  
  306.     // }}}
  307.     // {{{ getShortcuts()
  308.  
  309.     /**
  310.      * Get the list of command shortcuts.
  311.      *
  312.      * @return array shortcut => command
  313.      *
  314.      * @access public
  315.      * @static
  316.      */
  317.     function getShortcuts()
  318.     {
  319.         if (empty($GLOBALS['_PEAR_Command_shortcuts'])) {
  320.             PEAR_Command::registerCommands();
  321.         }
  322.         return $GLOBALS['_PEAR_Command_shortcuts'];
  323.     }
  324.  
  325.     // }}}
  326.     // {{{ getGetoptArgs()
  327.  
  328.     /**
  329.      * Compiles arguments for getopt.
  330.      *
  331.      * @param string $command     command to get optstring for
  332.      * @param string $short_args  (reference) short getopt format
  333.      * @param array  $long_args   (reference) long getopt format
  334.      *
  335.      * @return void
  336.      *
  337.      * @access public
  338.      * @static
  339.      */
  340.     function getGetoptArgs($command, &$short_args, &$long_args)
  341.     {
  342.         if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
  343.             PEAR_Command::registerCommands();
  344.         }
  345.         if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
  346.             return null;
  347.         }
  348.         $class = $GLOBALS['_PEAR_Command_commandlist'][$command];
  349.         $obj = &$GLOBALS['_PEAR_Command_objects'][$class];
  350.         return $obj->getGetoptArgs($command, $short_args, $long_args);
  351.     }
  352.  
  353.     // }}}
  354.     // {{{ getDescription()
  355.  
  356.     /**
  357.      * Get description for a command.
  358.      *
  359.      * @param  string $command Name of the command
  360.      *
  361.      * @return string command description
  362.      *
  363.      * @access public
  364.      * @static
  365.      */
  366.     function getDescription($command)
  367.     {
  368.         if (!isset($GLOBALS['_PEAR_Command_commanddesc'][$command])) {
  369.             return null;
  370.         }
  371.         return $GLOBALS['_PEAR_Command_commanddesc'][$command];
  372.     }
  373.  
  374.     // }}}
  375.     // {{{ getHelp()
  376.  
  377.     /**
  378.      * Get help for command.
  379.      *
  380.      * @param string $command Name of the command to return help for
  381.      *
  382.      * @access public
  383.      * @static
  384.      */
  385.     function getHelp($command)
  386.     {
  387.         $cmds = PEAR_Command::getCommands();
  388.         if (isset($cmds[$command])) {
  389.             $class = $cmds[$command];
  390.             return $GLOBALS['_PEAR_Command_objects'][$class]->getHelp($command);
  391.         }
  392.         return false;
  393.     }
  394.     // }}}
  395. }
  396.  
  397. ?>
  398.